#!/usr/bin/env python3
"""
DataPlexus 数据源管理依赖安装脚本
安装数据源管理功能所需的Python依赖包
"""

import sys
import os
import subprocess
import importlib
from typing import List, Dict, Tuple

# 数据源管理功能所需的依赖包
REQUIRED_DEPENDENCIES = {
    # 加密相关
    'cryptography': {
        'description': 'AES-256密码加密',
        'required': True,
        'install_cmd': 'pip install cryptography'
    },
    
    # 数据库驱动
    'aiomysql': {
        'description': 'MySQL异步驱动',
        'required': True,
        'install_cmd': 'pip install aiomysql'
    },
    'asyncpg': {
        'description': 'PostgreSQL异步驱动',
        'required': False,
        'install_cmd': 'pip install asyncpg'
    },
    'cx_Oracle': {
        'description': 'Oracle数据库驱动',
        'required': False,
        'install_cmd': 'pip install cx_Oracle',
        'notes': '需要Oracle Instant Client'
    },
    'pyodbc': {
        'description': 'SQL Server ODBC驱动',
        'required': False,
        'install_cmd': 'pip install pyodbc',
        'notes': '需要ODBC Driver for SQL Server'
    },
    
    # 其他工具
    'openpyxl': {
        'description': 'Excel文件处理（导入导出功能）',
        'required': False,
        'install_cmd': 'pip install openpyxl'
    }
}


class DependencyInstaller:
    """依赖安装器"""
    
    def __init__(self):
        self.installed = []
        self.failed = []
        self.skipped = []
    
    def check_package_installed(self, package_name: str) -> bool:
        """检查包是否已安装"""
        try:
            importlib.import_module(package_name)
            return True
        except ImportError:
            return False
    
    def install_package(self, package_name: str, install_cmd: str) -> Tuple[bool, str]:
        """安装单个包"""
        try:
            print(f"正在安装 {package_name}...")
            
            # 执行安装命令
            result = subprocess.run(
                install_cmd.split(),
                capture_output=True,
                text=True,
                timeout=300  # 5分钟超时
            )
            
            if result.returncode == 0:
                print(f"✅ {package_name} 安装成功")
                return True, "安装成功"
            else:
                error_msg = result.stderr or result.stdout
                print(f"❌ {package_name} 安装失败: {error_msg}")
                return False, error_msg
                
        except subprocess.TimeoutExpired:
            error_msg = "安装超时"
            print(f"❌ {package_name} 安装失败: {error_msg}")
            return False, error_msg
        except Exception as e:
            error_msg = str(e)
            print(f"❌ {package_name} 安装失败: {error_msg}")
            return False, error_msg
    
    def install_dependencies(self, install_optional: bool = False) -> Dict:
        """安装依赖包"""
        print("开始检查和安装数据源管理依赖包...")
        print("="*60)
        
        for package_name, info in REQUIRED_DEPENDENCIES.items():
            print(f"\n📦 处理包: {package_name}")
            print(f"   描述: {info['description']}")
            print(f"   必需: {'是' if info['required'] else '否'}")
            
            if info.get('notes'):
                print(f"   注意: {info['notes']}")
            
            # 检查是否已安装
            if self.check_package_installed(package_name):
                print(f"   状态: ✅ 已安装")
                self.installed.append({
                    'name': package_name,
                    'status': 'already_installed',
                    'description': info['description']
                })
                continue
            
            # 决定是否安装
            should_install = info['required'] or install_optional
            
            if not should_install:
                print(f"   状态: ⏭️ 跳过（可选包）")
                self.skipped.append({
                    'name': package_name,
                    'reason': 'optional',
                    'description': info['description']
                })
                continue
            
            # 安装包
            success, message = self.install_package(package_name, info['install_cmd'])
            
            if success:
                self.installed.append({
                    'name': package_name,
                    'status': 'newly_installed',
                    'description': info['description']
                })
            else:
                self.failed.append({
                    'name': package_name,
                    'error': message,
                    'description': info['description'],
                    'required': info['required']
                })
        
        return {
            'installed': self.installed,
            'failed': self.failed,
            'skipped': self.skipped
        }
    
    def print_summary(self, results: Dict):
        """打印安装总结"""
        print("\n" + "="*60)
        print("📋 依赖安装总结")
        print("="*60)
        
        # 已安装的包
        if results['installed']:
            print(f"\n✅ 已安装的包 ({len(results['installed'])}个):")
            for pkg in results['installed']:
                status_text = "新安装" if pkg['status'] == 'newly_installed' else "已存在"
                print(f"   • {pkg['name']} - {pkg['description']} ({status_text})")
        
        # 跳过的包
        if results['skipped']:
            print(f"\n⏭️ 跳过的包 ({len(results['skipped'])}个):")
            for pkg in results['skipped']:
                print(f"   • {pkg['name']} - {pkg['description']} (原因: {pkg['reason']})")
        
        # 失败的包
        if results['failed']:
            print(f"\n❌ 安装失败的包 ({len(results['failed'])}个):")
            for pkg in results['failed']:
                required_text = "必需" if pkg['required'] else "可选"
                print(f"   • {pkg['name']} - {pkg['description']} ({required_text})")
                print(f"     错误: {pkg['error']}")
        
        # 总体状态
        required_failed = [pkg for pkg in results['failed'] if pkg['required']]
        
        print(f"\n🎯 总体状态:")
        print(f"   成功安装: {len(results['installed'])}个")
        print(f"   跳过安装: {len(results['skipped'])}个")
        print(f"   安装失败: {len(results['failed'])}个")
        
        if required_failed:
            print(f"   ❌ 必需包安装失败: {len(required_failed)}个")
            print("   数据源管理功能可能无法正常工作")
        else:
            print("   ✅ 所有必需包安装成功")
            print("   数据源管理功能可以正常使用")
        
        print("\n" + "="*60)
    
    def print_next_steps(self, results: Dict):
        """打印后续步骤"""
        failed_optional = [pkg for pkg in results['failed'] if not pkg['required']]
        
        if failed_optional:
            print("\n📝 可选包安装建议:")
            for pkg in failed_optional:
                print(f"\n• {pkg['name']} ({pkg['description']}):")
                if pkg['name'] == 'cx_Oracle':
                    print("  1. 下载Oracle Instant Client:")
                    print("     https://www.oracle.com/database/technologies/instant-client.html")
                    print("  2. 配置环境变量")
                    print("  3. 重新运行: pip install cx_Oracle")
                elif pkg['name'] == 'pyodbc':
                    print("  1. 安装Microsoft ODBC Driver for SQL Server:")
                    print("     https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server")
                    print("  2. 重新运行: pip install pyodbc")
                else:
                    print(f"  重新运行: {REQUIRED_DEPENDENCIES[pkg['name']]['install_cmd']}")
        
        print("\n🚀 下一步操作:")
        print("1. 运行数据源管理初始化脚本:")
        print("   python scripts/setup_datasource_management.py")
        print("\n2. 或者分步执行:")
        print("   python scripts/init_datasource_permissions.py")
        print("   python scripts/add_datasource_route.py")


def main():
    """主函数"""
    print("DataPlexus 数据源管理依赖安装器")
    print("="*60)
    
    # 解析命令行参数
    install_optional = '--all' in sys.argv or '--optional' in sys.argv
    
    if install_optional:
        print("模式: 安装所有依赖（包括可选依赖）")
    else:
        print("模式: 仅安装必需依赖")
        print("提示: 使用 --all 参数安装所有依赖")
    
    try:
        installer = DependencyInstaller()
        results = installer.install_dependencies(install_optional)
        
        installer.print_summary(results)
        installer.print_next_steps(results)
        
        # 检查是否有必需包安装失败
        required_failed = [pkg for pkg in results['failed'] if pkg['required']]
        
        return len(required_failed) == 0
        
    except KeyboardInterrupt:
        print("\n⚠️ 安装被用户中断")
        return False
    except Exception as e:
        print(f"\n❌ 安装过程中发生错误: {str(e)}")
        return False


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)
